home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / misc / felix / source / processcomm.cpp < prev    next >
C/C++ Source or Header  |  1999-01-25  |  14KB  |  502 lines

  1.  //*************************************************************************//
  2. // Filename:    ProcessComm.cpp
  3. // Autor:       Christian Taulien of Strange Intelligence
  4. // Purpose:     Implementation für die Behandlung und die Kommunikation
  5. //              der Prozesse
  6. // Creation:    29. März 1998
  7. //*************************************************************************//
  8.  
  9. #include "global.h"
  10. #include "ProcessComm.h"
  11. #include "WindowList.h"
  12.  
  13. #include <string.h>
  14. #include <stdio.h>
  15.  
  16. #include <dos/dostags.h>
  17. #include <exec/types.h>
  18. #include <rexx/errors.h>
  19. #include <rexx/rxslib.h>
  20. #include <utility/tagitem.h>
  21.  
  22. #include <clib/dos_protos.h>
  23. #include <clib/exec_protos.h>
  24. #include <clib/rexxsyslib_protos.h>
  25. #include <clib/utility_protos.h>
  26. #include <clib/gadtools_protos.h>
  27.  
  28. extern FLXWatchListC *glob_poWatches;
  29.  
  30. struct MsgPort *glob_poReciever = NULL;
  31. struct MsgPort *glob_poStopper  = NULL;
  32. struct Process *glob_poWorker   = NULL;
  33. char  *glob_sPortName           = "GOLDED.1";
  34. WindowListC *glob_poWindowList = NULL;
  35.  
  36.  
  37. ULONG* SAVEDS SendRexxCommand(UBYTE *port, UBYTE *cmd, struct MsgPort *replyPort)
  38. /*S*/
  39. {
  40.   TRACE("Entry");
  41.   Forbid();
  42.  
  43.   struct MsgPort *rexxport;
  44.   if (rexxport = FindPort(port))
  45.   {
  46.     struct RexxMsg *rexxMsg, *answer;
  47.     if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL))
  48.     {
  49.       if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd)))
  50.       {
  51.         static ULONG result;
  52.  
  53.         rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
  54.         PutMsg(rexxport, &rexxMsg->rm_Node);
  55.  
  56.         if (replyPort)
  57.         {
  58.           do
  59.           {
  60.             WaitPort(replyPort);
  61.             if (answer = (struct RexxMsg *)GetMsg(replyPort))
  62.             {
  63.               result = answer->rm_Result1;
  64.             } // if
  65.           } while (!answer);
  66.         } // if
  67.  
  68.         Permit();
  69. //        TRACE("zurück vom msg verschicken.");
  70.  
  71.         if (replyPort)
  72.         {
  73.           if (answer->rm_Result1 == RC_OK)
  74.           {
  75.             if (answer->rm_Result2)
  76.             {
  77.               DeleteArgstring((UBYTE *)answer->rm_Result2);
  78.             } // if
  79.           } // if
  80.  
  81.           DeleteArgstring((UBYTE *)ARG0(answer));
  82.           DeleteRexxMsg(answer);
  83.         } // if
  84.         return &result;
  85.       } // if
  86.     } // if
  87.   } // if
  88.   Permit();
  89.  
  90. return NULL;
  91. }
  92. /*E*/
  93. void DispatchMessage(struct Message *arg_poMessage, BOOL arg_bAsync)
  94. /*S*/
  95. {
  96.   TRACE("Entry");
  97.   // bis jetzt noch kein richtiger dispatcher
  98.   // solange wir was zum verschicken haben, schicken wir das einfach los
  99.   if (arg_poMessage && arg_poMessage->mn_Node.ln_Name)
  100.   {
  101.     // wenn kein Asyncronen-Command
  102.     if (arg_bAsync || Strnicmp("QUIT", arg_poMessage->mn_Node.ln_Name, 4)==0)
  103.     {
  104.       TRACE(arg_poMessage->mn_Node.ln_Name);
  105.       SendRexxCommand(glob_sPortName, arg_poMessage->mn_Node.ln_Name, NULL);
  106. //      TRACE("Asyncronen Befehl an Golded geschickt");
  107.     }
  108.     else
  109.     {
  110.       struct MsgPort *msgPort;
  111.       if (msgPort = CreateMsgPort())
  112.       {
  113.         TRACE(arg_poMessage->mn_Node.ln_Name);
  114.         SendRexxCommand(glob_sPortName, arg_poMessage->mn_Node.ln_Name, msgPort);
  115. //        TRACE("Befehl an Golded geschickt");
  116.         DeleteMsgPort(msgPort);
  117.       } // if
  118.     } // if
  119.     delete arg_poMessage->mn_Node.ln_Name;
  120.     delete arg_poMessage;
  121.   } // if
  122. }
  123. /*E*/
  124. void sendMsgToGoldED(char *arg_sCommand, char *arg_sParameter, BOOL arg_bAsync)
  125. /*S*/
  126. {
  127.   TRACE("Entry");
  128.   if (!arg_sParameter)
  129.   {
  130.     arg_sParameter = "";
  131.   } // if
  132.  
  133.   // allocate the mem for the command-string
  134.   char *sCommand = new char [strlen(arg_sCommand)+strlen(arg_sParameter)+2];
  135.   if (sCommand)
  136.   {
  137.     sprintf(sCommand, arg_sCommand, arg_sParameter);
  138.  
  139.     struct Message *poMessage = new struct Message;
  140.     if (poMessage)
  141.     {
  142.       memset(poMessage, 0, sizeof(struct Message));
  143.       poMessage->mn_Length = sizeof(struct Message);
  144.       poMessage->mn_Node.ln_Name = sCommand;
  145.  
  146. //      TRACE("msg weitergeleitet:");
  147. //      TRACE(sCommand);
  148.       DispatchMessage(poMessage, arg_bAsync);
  149.     }
  150.     else
  151.     {
  152.       delete sCommand;
  153.     } // if
  154.   } // if
  155. //  Delay(50);
  156. }
  157. /*E*/
  158. void SAVEDS handleAPIRemoteCmdMsg(FelixMessage *arg_poFLXMsg)
  159. /*S*/
  160. {
  161.   TRACE("Entry");
  162.   if (!arg_poFLXMsg || !arg_poFLXMsg->m_poTagList || arg_poFLXMsg->m_ulType!=FelixMessage::FLXMSG_REMOTECMD)
  163.   {
  164.     return;
  165.   } // if
  166.  
  167.   switch (GetTagData(FLXTAG_REMOTECOMMAND, FLXWINDOWCMD_UNDEFINED, arg_poFLXMsg->m_poTagList))
  168.   {
  169.     case FLXREMOTECMD_RELOADFILE:
  170. //      TRACE("Datei soll nachgeladen werden");
  171.       { // dummy scope
  172.         char *sFileName = (char *)GetTagData(FLXTAG_FileName, 0, arg_poFLXMsg->m_poTagList);
  173.  
  174.         if (sFileName)
  175.         {
  176.           sendMsgToGoldED("WINDOW QUIET USE=\"%s\"", sFileName, TRUE);
  177.           sendMsgToGoldED("OPEN AGAIN FORCE NAME \"%s\"", sFileName, TRUE);
  178.           sendMsgToGoldED("GOTO CHANGE","", TRUE);
  179.         } // if
  180.       }
  181.       break;
  182.     default:
  183. //      TRACE("Unbekannte remotecmd-msg");
  184.       break;
  185.   } // switch
  186. }
  187. /*E*/
  188. void SAVEDS handleAPIWindowMsg(FelixMessage *arg_poFLXMsg)
  189. /*S*/
  190. {
  191.   TRACE("Entry");
  192.   if (!arg_poFLXMsg || !arg_poFLXMsg->m_poTagList || arg_poFLXMsg->m_ulType!=FelixMessage::FLXMSG_WINDOWLIST)
  193.   {
  194.     return;
  195.   } // if
  196.  
  197.   switch (GetTagData(FLXTAG_WINDOWCOMMAND, FLXWINDOWCMD_UNDEFINED, arg_poFLXMsg->m_poTagList))
  198.   {
  199.     case FLXWINDOWCMD_OPEN:
  200. //      TRACE("Fenster soll geöffnet werden");
  201.       { // dummy scope
  202.         struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
  203.         if (apiMsg)
  204.         {
  205.           // wenn es noch keine Fensterliste gibt
  206.           if (!glob_poWindowList)
  207.           {
  208.             // eine anlegen
  209.             glob_poWindowList = new WindowListC(glob_poWatches);
  210.           } // if
  211.  
  212.           // wenn es jetze ein Fenster gibt
  213.           if (glob_poWindowList)
  214.           {
  215.             static BOOL bStartedOnce = FALSE;
  216.             BOOL bKeepPos = GetTagData(FLXTAG_KeepPos, FALSE, arg_poFLXMsg->m_poTagList);
  217.             // wenn noch nicht gestartet
  218.             if (!bStartedOnce || !bKeepPos)
  219.             {
  220.               ULONG ulX = GetTagData(FLXTAG_Left, -1, arg_poFLXMsg->m_poTagList);
  221.               ULONG ulY = GetTagData(FLXTAG_Top, -1, arg_poFLXMsg->m_poTagList);
  222.               glob_poWindowList->setWindowPosition(ulX, ulY, TRUE);
  223.               bStartedOnce = TRUE;
  224.             } // if
  225.  
  226.             ULONG ulEntries = GetTagData(FLXTAG_Entries, 20, arg_poFLXMsg->m_poTagList);
  227.             glob_poWindowList->setMaxVisibleEntries(ulEntries);
  228.  
  229.             glob_poWindowList->openWindowList(apiMsg);
  230.             glob_poWindowList->updateWindowList(apiMsg->api_Instance);
  231.           } // if
  232.         } // if
  233.         else
  234.         {
  235. //          TRACE("kein FLXTAG_APIMSG in der TagList");
  236.         } // if
  237.       } // dummy scope
  238.       break;
  239.     case FLXWINDOWCMD_TEXTMODIFY:
  240. //      TRACE("Text wurde verändert");
  241.       if (glob_poWindowList)
  242.       {
  243.         struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
  244.         glob_poWindowList->updateModifiedFlag(apiMsg->api_Instance);
  245.       } // if
  246.       break;
  247.     case FLXWINDOWCMD_CLOSE:
  248. //      TRACE("Fenster soll geschlossen werden");
  249.       if (glob_poWindowList)
  250.       {
  251.         delete glob_poWindowList;
  252.         glob_poWindowList = NULL;
  253.       }
  254.       break;
  255.     case FLXWINDOWCMD_UPDATE:
  256. //      TRACE("Fenster soll geupdatet werden");
  257.       if (glob_poWindowList)
  258.       {
  259.         struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
  260.         if (apiMsg)
  261.         {
  262.           glob_poWindowList->updateWindowList(apiMsg->api_Instance);
  263.         } // if
  264.       } // if
  265.       break;
  266.     case FLXWINDOWCMD_CREATED:
  267.       if (glob_poWindowList)
  268.       {
  269.         struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
  270.         glob_poWindowList->getWNameList()->findWName(apiMsg->api_Instance)->m_bModified = FALSE;
  271.         GT_RefreshWindow(glob_poWindowList->getWindow(),0);
  272.         glob_poWindowList->refreshDesign();
  273.       }
  274.     default:
  275. //      TRACE("Unbekannte windowlist-msg");
  276.       break;
  277.   }
  278.  
  279. }
  280. /*E*/
  281. BOOL SAVEDS handleAPIMessage(struct Message *arg_poMessage)
  282. /*S*/
  283. {
  284.   TRACE("Entry");
  285.  
  286.   if (!arg_poMessage)
  287.   {
  288. //    TRACE("Falscher Parameter!");
  289.     return FALSE;
  290.   } // if
  291.  
  292.   char *sName = arg_poMessage->mn_Node.ln_Name;
  293.   TRACE(sName);
  294.   if (sName)
  295.   {
  296.     // Ist es die ende-Msg?
  297.     if (0 == strcmp("ende", sName))
  298.     {
  299. //      TRACE("Ende-Message erkannt");
  300.       // wenn die WindowList noch offen ist
  301.       if (glob_poWindowList)
  302.       {
  303.         delete glob_poWindowList;
  304.         glob_poWindowList = NULL;
  305.       } // if
  306.       return TRUE;
  307.     }
  308.     // ist es eine message für die WindowList-verwaltung
  309.     else if (0 == strcmp("windowlist", sName))
  310.     {
  311. //      TRACE("WindowListMessage erhalten");
  312.       FelixMessage *poFLXMsg = (FelixMessage *) arg_poMessage;
  313.       handleAPIWindowMsg(poFLXMsg);
  314.     }
  315.     else if (0 == strcmp("remote", sName))
  316.     {
  317. //      TRACE("An ein befehl soll verschickt werden")
  318.       FelixMessage *poFLXMsg = (FelixMessage *) arg_poMessage;
  319.       handleAPIRemoteCmdMsg(poFLXMsg);
  320.     } // if
  321.   } // if
  322.   ReplyMsg(arg_poMessage);
  323. return FALSE;
  324. }
  325. /*E*/
  326. void BuildWaitMask(const struct MsgPort *arg_poMsgPort, ULONG &arg_rulMask)
  327. /*S*/
  328. {
  329. //  TRACE("Entry");
  330.   if (!arg_poMsgPort)
  331.   {
  332. //    TRACE("Kein Msg-Port");
  333.     return;
  334.   } // if
  335.  
  336.   arg_rulMask |= (1L << (arg_poMsgPort->mp_SigBit));
  337. }
  338. /*E*/
  339. void SAVEDS EntprellePort(struct MsgPort *arg_poPort)
  340. /*S*/
  341. {
  342.   TRACE("Entry");
  343.   if (!arg_poPort)
  344.   {
  345.     return;
  346.   }
  347.  
  348.   struct Message *poMessage;
  349.   // solange wir messages kriegen
  350.   while (poMessage = GetMsg(arg_poPort))
  351.   {
  352.     // Wenn die Message einen ReplyPort hat
  353.     if (poMessage->mn_ReplyPort)
  354.     {
  355.       ReplyMsg(poMessage);
  356.     } // if
  357.   } // while
  358. }
  359. /*E*/
  360.  
  361. void SAVEDS FelixTask(void)
  362. /*S*/
  363. {
  364.   TRACE("Entry");
  365.   struct Message *poMessage = NULL;
  366.   if (glob_poReciever = CreateMsgPort())
  367.   {
  368.     // wenn der Empfänger-Port vorhanden ist
  369.     if (glob_poReciever)
  370.     {
  371.       BOOL done = FALSE;
  372.       while(!done)
  373.       {
  374. //        TRACE("Thread-msg-schleife");
  375.         ULONG ulSigMask = NULL;
  376.         BuildWaitMask(glob_poReciever, ulSigMask);
  377.         // wenn auch ein fenster existiert
  378.         if (glob_poWindowList && glob_poWindowList->getWindow())
  379.         {
  380.           BuildWaitMask(glob_poWindowList->getWindow()->UserPort, ulSigMask);
  381.         } // if
  382. //        TRACE("go waiting...");
  383.         Wait(ulSigMask);
  384. //        TRACE("waking up...");
  385.  
  386.         while (!done && (poMessage = GetMsg(glob_poReciever)))
  387.         {
  388. //          TRACE("GetMsg()-schleife für api");
  389.           done = handleAPIMessage(poMessage);
  390. //          TRACE("zurück von handleapimsg()");
  391.           // ! diese Messages müssen nicht beantwortet werden !
  392.         } // while
  393.  
  394.         if (!done && glob_poWindowList)
  395.         {                             
  396. //          TRACE("Versuche handleWindowList");
  397.           BOOL bClose = glob_poWindowList->handleWindowList();
  398.           if (bClose)
  399.           {
  400.             delete glob_poWindowList;
  401.             glob_poWindowList = NULL;
  402.           } // if
  403.         } // if
  404.       } // while
  405.  
  406.       // Aufräumen
  407.       EntprellePort(glob_poReciever);
  408.       DeleteMsgPort(glob_poReciever);
  409.       glob_poReciever = NULL;
  410.     } // if
  411.  
  412.     // Message jetzt zurückschicken
  413.     glob_poWorker = NULL;
  414. //    TRACE("Steige jetzt wieder aus");
  415.     if (poMessage)
  416.     {
  417.       PutMsg(glob_poStopper, poMessage);
  418.     }
  419.     else
  420.     {
  421. //      TRACE("exit ohne message!!!");
  422.     } // if
  423.   } // if
  424. }
  425. /*E*/
  426. void SendeNachricht(char *arg_sName, UBYTE arg_uyMsgType, ULONG arg_eTags ...)
  427. /*S*/
  428.   TRACE("Entry");
  429.   SendeNachrichtA(arg_sName, arg_uyMsgType, (struct TagItem *) &arg_eTags);
  430. }
  431. /*E*/
  432. void SendeNachrichtA(char *arg_sName, UBYTE arg_uyMsgType, struct TagItem *arg_poTagList)
  433. /*S*/
  434. {
  435.   TRACE("Entry");
  436.   struct MsgPort *poPort;
  437.   // Wenn Stopper-Port vorhanden
  438.   if (poPort = CreateMsgPort())
  439.   {
  440.     // Wenn Reciever-Port vorhanden
  441.     if (glob_poReciever && glob_poWorker)
  442.     {
  443.       struct FelixMessage oMessage;
  444.       memset(&oMessage, 0, sizeof(struct FelixMessage));
  445.       oMessage.mn_Length = sizeof(struct FelixMessage);
  446.       oMessage.mn_Node.ln_Name = arg_sName;
  447.       oMessage.m_ulType        = arg_uyMsgType;
  448.       oMessage.m_poTagList     = arg_poTagList;
  449.       oMessage.mn_ReplyPort    = poPort;
  450.  
  451. //      TRACE("schicke Nachricht");
  452.       PutMsg(glob_poReciever, &oMessage);
  453. //      TRACE("Nachricht abgeschickt");
  454.       WaitPort(poPort);
  455. //      TRACE("Zurück von warte auf reply");
  456.     } // if
  457.     DeleteMsgPort(poPort);
  458.   } // if
  459. }
  460. /*E*/
  461. void BeendeProzess(void)
  462. /*S*/
  463. {
  464.   TRACE("Entry");
  465.   // Wenn Stopper-Port vorhanden
  466.   if (glob_poStopper = CreateMsgPort())
  467.   {
  468.     // Wenn Reciever-Port vorhanden
  469.     if (glob_poReciever)
  470.     {
  471.       // Wenn der Prozess auch vorhanden
  472.       if (glob_poWorker)
  473.       {
  474.         struct Message oMessage;
  475.         memset(&oMessage, 0, sizeof(struct Message));
  476.         oMessage.mn_Length = sizeof(struct Message);
  477.         oMessage.mn_Node.ln_Name = "ende";
  478.  
  479.         PutMsg(glob_poReciever, &oMessage);
  480. //        TRACE("Ende-Message abgeschickt");
  481.         WaitPort(glob_poStopper);
  482.       } // if
  483.     } // if
  484.     EntprellePort(glob_poStopper);
  485.     DeleteMsgPort(glob_poStopper);
  486.     glob_poStopper = NULL;
  487.   } // if
  488. }
  489. /*E*/
  490. void StarteProzess(void)
  491. /*S*/
  492. {
  493.   TRACE("Entry");
  494.   glob_poWorker = CreateNewProcTags(NP_Entry, FelixTask,
  495.                                     NP_Priority, FindTask(NULL)->tc_Node.ln_Pri + 5,
  496.                                     NP_Name, "Felix-Task (GoldED-API)",
  497.                                     TAG_DONE);
  498. }
  499. /*E*/
  500.  
  501.